package com.cbg.base.core;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cbg.base.constant.Constant;
import com.cbg.base.utils.Result;
import com.cbg.dg.jwt.JwtUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.Optional;

/**
 * Controller通用父类
 * @author chenbing
 * @时间 2018年6月6日 下午7:09:29
 */
public abstract class SuperController<M extends SuperService<T>,T extends SuperEntity> {
	@Autowired
	M baseService;

	@ApiOperation(value="通过ID查询", notes="通过ID查询")
	@ApiImplicitParam(name = "id", value = "查询主键ID", required = true, dataType = "String", paramType = "path")
	@GetMapping("/{id}")
	Result<?> getById(@PathVariable String id){
		return Result.ok(baseService.getById(id));
	}

	@ApiOperation(value="查询列表", notes="查询列表")
	@GetMapping("/list")
	Result<?> list(){
		return Result.ok(baseService.list());
	}

	@ApiOperation(value="通过ID删除", notes="通过ID删除")
	@ApiImplicitParam(name = "id", value = "查询主键ID", required = true, dataType = "String", paramType = "path")
	@DeleteMapping("/{id}")
	Result<?> delById(@PathVariable String id){
		return Result.ok(baseService.removeById(id));
	}

	@ApiOperation(value="新增实体", notes="新增实体")
	@ApiImplicitParam(name = "t", value = "实体对象T", required = true, dataType = "T", paramType = "query")
	@PostMapping
	Result<?> insert(T t){
		return Result.ok(baseService.save(t));
	}

	@ApiOperation(value="通过id更新实体", notes="参数需要id和实体t")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "实体id", required = true, dataType = "String",paramType = "path"),
			@ApiImplicitParam(name = "t", value = "更新实体", required = true, dataType = "T",paramType = "query")
	})
	@PutMapping("/{id}")
	Result<?> update(@PathVariable String id,T t){
		baseService.update(t,new QueryWrapper<T>().eq("id",id));
		return Result.ok();
	}

	@ApiOperation(value="页查询，支持选择单字段排序分页", notes="不支持字段筛选通用分页查询，条件筛选分页时，修改new QueryWrapper<>()自定义分页方法。参数统一处理了。")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer",paramType = "query"),
			@ApiImplicitParam(name = "pageSize", value = "每页记录数", required = true, dataType = "Integer",paramType = "query")
	})
	@GetMapping("/page")
	Result<?> listByPage(){
		Page<T> page = page();
		String sort=WebUtils.findParameterValue(request(), "sort");
		if(!Optional.ofNullable(sort).isPresent())
			return Result.ok(baseService.page(page, null));
		String order = request().getParameter("order");
		if("ASC".equalsIgnoreCase(order))
			page.setAsc(sort);
		if ("DESC".equalsIgnoreCase(order))
			page.setDesc(sort);
		return Result.ok(baseService.page(page,null));
	}

	private Page<T> page() {
		int pageNum = param2Int("pageNum", 1);
		int pageSize = param2Int("pageSize",10);
		return new Page<>(pageNum, pageSize);
	}

	private int param2Int(String param, int defaultVal) {
		String value = WebUtils.findParameterValue(request(), param);
		return StrUtil.isBlank(value) ? defaultVal : Integer.parseInt(value);
	}

	/**
	 * 获取request对象
	 */
	public HttpServletRequest request() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		Objects.requireNonNull(attributes,"request为null");
		return attributes.getRequest();
	}

	/**
	 * 获取response对象
	 */
	public HttpServletResponse response() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		Objects.requireNonNull(attributes,"request为null");
		return attributes.getResponse();
	}

	/**
	 * 获取userId
	 */
	public String userId(){
		String token = request().getHeader(Constant.TOKEN);
		return JwtUtils.getUserId(token);
	}
}